package com.daervin.svc.service.impl;

import com.daervin.svc.common.dto.NewsDTO;
import com.daervin.svc.common.dto.NewsSimpleDTO;
import com.daervin.svc.common.utils.DateTimeUtils;
import com.daervin.svc.common.utils.JsonUtil;
import com.daervin.svc.dal.INewsDao;
import com.daervin.svc.dal.ISpiderInfoDao;
import com.daervin.svc.dal.model.News;
import com.daervin.svc.dal.model.SpiderInfo;
import com.daervin.svc.helper.BlockingQueueHelper;
import com.daervin.svc.helper.FilterHelper;
import com.daervin.svc.service.ILocalCacheService;
import com.daervin.svc.service.INewsService;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author daervin
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class NewsServiceImpl implements INewsService {

    private final static Logger LOGGER = Logger.getLogger(NewsServiceImpl.class);

    @Resource
    private INewsDao newsDao;

    @Resource
    private ISpiderInfoDao spiderInfoDao;
    @Autowired
    private ILocalCacheService localCacheService;

    @Override
    public void delBeforeData() {
        newsDao.deleteAll(DateTimeUtils.getBeforeDefault());
    }

    @Override
    public int addBatch(List<News> news) {
        return newsDao.insert(news);
    }

    @Override
    public void commonAdd(List<NewsDTO> newsList, String name) {
        BlockingQueueHelper.put(newsList);
    }

    @Override
    public void takeProcess() {
        List<NewsDTO> newsList = BlockingQueueHelper.take();
        if (CollectionUtils.isEmpty(newsList)) {
            return;
        }
        String name = "news-process";
//            this.delBeforeData();
        newsList.sort(Comparator.comparingInt(NewsDTO::getCategory).reversed().thenComparing(NewsDTO::getBelongDate));
        String announcer = newsList.get(0).getAnnouncer();
        System.out.println("***************************************" + announcer);
//        LOGGER.info("***************************************");
        List<News> resultList = new ArrayList<>();
        List<NewsSimpleDTO> existDataList = getAllExistData();

        for (NewsDTO item : newsList) {
//            LOGGER.info(JsonUtil.toString(item));
//            System.out.println(JsonUtil.toString(item));
            System.out.println(item.getTitle());

            News news = new News();
            news.setTitle(item.getTitle());
            news.setDescription(item.getDesc());
            news.setAnnouncer(item.getAnnouncer());
            news.setCategory(item.getCategory());
            news.setLinks(item.getLinks() == null ? "" : item.getLinks());
            news.setStatus(1);
            news.setPid(0L);
            String dateString = item.getBelongDate();
            if (dateString != null) {
                news.setBelongDate(DateTimeUtils.longParseDate(dateString));
            }
            if (!FilterHelper.news(item, news)) {
                System.out.println("------------------filter--------------------");
//                LOGGER.info("------------------filter--------------------");
                System.out.println("---------------------------------------");
                continue;
            }
            // 分析去重
            NewsSimpleDTO analysis = FilterHelper.analysis(item, existDataList, item.getCategory());
            if (analysis != null) {
                if (analysis.getAnnouncer().equalsIgnoreCase(item.getAnnouncer()) || (analysis.getPid() != null && analysis.getPid() > 0)) {
                    System.out.println("------------------same--------------------");
//                LOGGER.info("------------------same--------------------");
                    System.out.println("---------------------------------------");
                    continue;
                }
                System.out.println(String.format("---------analysis------[%s_%s_%s]", analysis.getId(), analysis.getTitle(), analysis.getRate()));
//                LOGGER.info("------------------analysis--------------------");
                news.setStatus(2);
                news.setPid(analysis.getId());
            }
            System.out.println("---------------------------------------");
//            LOGGER.info("---------------------------------------");
            // 获取短链接
//            if (!StringUtils.isEmpty(item.getLinks())) {
//                ShortUrlDTO shortUrl = ShortUrlUtil.getShortUrl(item.getLinks());
//                if (shortUrl == null || StringUtils.isEmpty(shortUrl.getLongUrl())) {
//                    news.setDwzUrl(shortUrl.getLongUrl());
//                }
//            }
            resultList.add(news);
        }

        if (!CollectionUtils.isEmpty(resultList)) {
            System.out.println("------------------addBatch---------------------" + resultList.size());
            this.addBatch(resultList);
            addOrUpdateSpiderInfo(name);
            reloadExistData();
        }
    }

    @Override
    public void addOrUpdateSpiderInfo(String name) {
        SpiderInfo info = spiderInfoDao.getByName(name);
        Date currentTime = Calendar.getInstance().getTime();
        if (info == null) {
            info = new SpiderInfo();
            info.setName(name);
            info.setLastTime(currentTime);
            spiderInfoDao.insert(info);
            return;
        }

        info.setLastTime(currentTime);
        spiderInfoDao.update(info);
    }

    @Override
    public List<NewsSimpleDTO> getAllExistData() {
        List<NewsSimpleDTO> all = localCacheService.getValue("all-news", new TypeReference<List<NewsSimpleDTO>>() {
        }, () -> {
            try {
                List<News> allNews = newsDao.selectsAll(null);
                List<NewsSimpleDTO> dots = new ArrayList<>();
                if (!CollectionUtils.isEmpty(allNews)) {
                    allNews.stream().forEach(item -> {
                        dots.add(new NewsSimpleDTO(item.getId(), item.getTitle(), item.getAnnouncer(), item.getPid()));
                    });
                }
                return JsonUtil.toString(dots);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        });
        return all;
    }

    private void reloadExistData() {
        try {
            List<News> allNews = newsDao.selectsAll(null);
            List<NewsSimpleDTO> dots = new ArrayList<>();
            if (!CollectionUtils.isEmpty(allNews)) {
                allNews.stream().forEach(item -> {
                    dots.add(new NewsSimpleDTO(item.getId(), item.getTitle(), item.getAnnouncer(), item.getPid()));
                });
                localCacheService.put("all-news", JsonUtil.toString(dots));
            }
        } catch (Exception e) {
            LOGGER.error("reloadExistData error", e);
        }
    }
}
